﻿using Nancy;
using Nancy.Diagnostics;
using Nancy.Hosting.Self;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace aaAttributeBrowser
{
#if DEBUG
    public class CustomBootstrapper : DefaultNancyBootstrapper
    {
        protected override DiagnosticsConfiguration DiagnosticsConfiguration
        {
            get { return new DiagnosticsConfiguration { Password = @"Test" }; }
        }
    }
#endif

    public class NancyStuff : NancyModule
    {
        private static readonly log4net.ILog _log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        public NancyStuff()
        {
            Get["/alarms/{req}"] = parameters =>
            {
                _log.Debug(string.Format("Request recieved /alarms/{{req}} req={0}", parameters.req));
                return AlarmManager.Singleton.Handle(parameters.req);
            };

            Get["/alarms/alarms"] = parameters =>
            {
                _log.Debug("Request recieved /alarms/alarms");
                //return the all of the system alarms in json format
                return AlarmManager.Singleton.GetAlarmJSON();
            };
               
            //This will return all of the objects currently deployed in a galaxy, with their object types and descriptions
            Get["/__allObjects/{gal}"] = parameters =>
            {
                _log.Debug("Request recieved /__allObjects/{gal}");
                string response = new DeployedObjects().GetAllObjects(parameters.gal);
                if (response == "")
                {
                    return 404;
                }
                else
                {
                    return response;
                }
            };

            Get["/object/{obj}"] = parameters =>
            {
                try
                {
                    _log.Info(string.Format("Request recieved /object/{{obj}} req={0}", parameters.obj));
                    string response = aaAttributeManager.Singleton.GetObjectJSON(parameters.obj);
                    if (response == "")
                    {
                        return 404;
                    }
                    else
                    {
                        return response;
                    }
                }
                 catch( Exception ex)
                {
                    //this is most likely when MxAccess is not available
                    _log.Error(ex.ToString());
                    return HttpStatusCode.ServiceUnavailable;
                }
            };

            Get["/object/{obj}/fresh"] = parameters =>
            {
                _log.Info("Request recieved /object/{obj}/fresh");
                aaAttributeManager.Singleton.RemoveObject(parameters.obj);
                string response = aaAttributeManager.Singleton.GetObjectJSON(parameters.obj);
                if (response == "")
                {
                    return 404;
                }
                else
                {
                    return response;
                }
            };

            Get["/object/{obj}/delete"] = parameters =>
            {
                _log.Info("Request recieved /object/{obj}/delete");
                if (aaAttributeManager.Singleton.RemoveObject(parameters.obj))
                {
                    return 200;
                }
                else
                {
                    return 404;
                }
            };
            Get["/objects/cache"] = parameters =>
            {
                _log.Info("Request recieved /objects/cache");
                return aaAttributeManager.Singleton.ObjectCache();
            };
            Get["/objects/emptycache"] = parameters =>
            {
                _log.Info("Request recieved /objects/emptycache");
                return aaAttributeManager.Singleton.EmptyCache();
            };
        }
    }

    public class Nancy
    {
        private static readonly log4net.ILog _log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        private NancyHost _host; //handles the http requests
        
        /// <summary>
        /// The port number to listen on
        /// </summary>
        public int ListenPort { get; set; }

        public Nancy()
        {
            ListenPort = 8123;
        }

        /// <summary>
        /// Start the http server and respond to requests
        /// </summary>
        public bool StartListening(bool https = false)
        {
            try
            {
                if (https)
                    _host = new NancyHost(new Uri(string.Format("https://localhost:{0}/", ListenPort)));
                else
                    _host = new NancyHost(new Uri(string.Format("http://localhost:{0}/", ListenPort)));
                _host.Start();

                _log.Info(string.Format("Starting Nancy on port {0}", ListenPort));
                return true;
            }
            catch (Exception ex)
            {
                _log.Error(ex.ToString());
                return false;
            }
        }

        /// <summary>
        /// Stop the http server
        /// </summary>
        public void StopListening()
        {
            if (_host != null)
            {
                _log.Info("Stopping Nancy");
                _host.Stop();
                _host.Dispose();
                _host = null;
            }
        }
    }
}
